package com.zhihuishu.treenity.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import org.apache.commons.io.FileUtils;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.zhihuishu.treenity.helper.UUIDHelper;

/**
 * @author hgg 图片处理类
 */
@SuppressWarnings("restriction")
public class ImageUtil {

	private static final float MEDIUM_QUALITY = 0.75F;
	private static final float HIGH_QUALITY = 1.0F;
	private static final float DEFALUT_QUALITY = 0.5F;
	private static final float LOW_QUALITY = 0.25F;
	private static final float LOWEST_QUALITY = 0.1F;

	public static final String CENTER = "C";
	public static final String BOTTOM_LEFT = "L";
	public static final String BOTTOM_RIGTH = "R";
	private static final int WIDTH170 = 170;
	private static final int WIDTH198 = 198;
	private static final int WIDTH50 = 50;
	private static final int WIDTH300 = 300;
	private static final int WIDTH30 = 30;
	private static final int WIDTH100 = 100;
	private static final int LENGTH120 = 120;
	private static final int WIDTH360 = 360;
	private static final int WIDTH440 = 440;
	private static final int WIDTH966 = 966;
	@SuppressWarnings("unused")
	private static final int WIDTH1024 = 1024;
	@SuppressWarnings("unused")
	private static final int WIDTH1600 = 1600;

	private static final int ONE_SIZE_M = 1 * 1024 * 1024;
	private static final int TWO_SIZE_M = 2 * 1024 * 1024;
	private static final int THREE_SIZE_M = 3 * 1024 * 1024;
	private static final int FOUR_SIZE_M = 4 * 1024 * 1024;
	private static final int FIVE_SIZE_M = 5 * 1024 * 1024;

	private static final String _FONTNAME = null;
	private static final int _FONTSTYLE = 0;
	private static final int _COLOR = 0;

	/**
	 * 加载图片
	 * 
	 * @param srcImg
	 * @return
	 */
	public static Image toImage(String src) {
		Image img = null;
		/*
		 * Toolkit toolkit = Toolkit.getDefaultToolkit(); img =
		 * toolkit.getImage(srcImg);
		 */
		try {
			File srcFile = new File(src);
			img = ImageIO.read(srcFile);
		} catch (IOException e) {
			e.printStackTrace();
		}

		return img;
	}

	/**
	 * 加载图片
	 * 
	 * @param srcImg
	 * @return
	 */
	public static Image toImage(File srcFile) {
		Image img = null;
		try {
			img = ImageIO.read(srcFile);
		} catch (IOException e) {
			e.printStackTrace();
		}

		return img;
	}

	/**
	 * 加载图片
	 * 
	 * @param srcImg
	 * @return
	 */
	public static Image toImage(InputStream in) {
		Image img = null;
		try {
			img = ImageIO.read(in);
		} catch (IOException e) {
			e.printStackTrace();
		}

		return img;
	}

	private static void render(int width, int height, Image srcImg, String target, float quality) {
		FileOutputStream out = null;
		try {
			BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

			Graphics g = bimg.createGraphics();
			g.drawImage(srcImg, 0, 0, width, height, null);
			out = new FileOutputStream(target);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(bimg);
			if (quality != 0)
				jep.setQuality(quality, true);
			encoder.encode(bimg, jep);
		} catch (ImageFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 不会生成图片，由内存写到另一个内存
	 * 
	 * @param width
	 * @param height
	 * @param srcImg
	 * @param target
	 * @param quality
	 */
	public static void render2(int width, int height, Image srcImg, OutputStream target, float quality) {
		try {
			BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			Image image = srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH);

			Graphics g = bimg.createGraphics();
			g.drawImage(image, 0, 0, width, height, null);

			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(target);
			JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(bimg);
			if (quality != 0)
				jep.setQuality(quality, true);

			encoder.encode(bimg, jep);
		} catch (ImageFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
		}
	}

	/**
	 * 判断文件路径是否正确
	 * 
	 * @param src
	 */
	private static File checkForNull(String src) {
		return checkForNull(src, "Cannot specify null for input files.");
	}

	private static File checkForNull(String src, String message) {
		if (src == null) {
			// throw new FileUploadException(message);
		}
		File f = new File(src);
		if (!f.exists()) {
			// throw new FileUploadException(message);
		}
		return f;
	}

	/**
	 * 调整大小：100*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static String resize100(String src, String target) {
		File srcFile = checkForNull(src);
		Image srcImg = toImage(srcFile);
		if (srcImg.getWidth(null) < WIDTH100)
			return src;
		return resize(WIDTH100, srcImg, target);
	}

	/**
	 * 调整大小：360*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static String resize360(String src, String target) {
		File srcFile = checkForNull(src);
		Image srcImg = toImage(srcFile);
		if (srcImg.getWidth(null) < WIDTH360)
			return src;
		return resize(WIDTH360, srcImg, target);
	}

	/**
	 * 调整大小：966*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static String resize966(String src, String target) {
		File srcFile = checkForNull(src);
		Image srcImg = toImage(srcFile);
		if (srcImg.getWidth(null) < WIDTH966)
			return src;
		return resize(WIDTH966, srcImg, target);
	}

	public static String resize(int _width, Image srcImg, String target) {
		int width = srcImg.getWidth(null);
		int height = srcImg.getHeight(null);

		float s = getRatio(width, _width);
		int h = (int) (height * s);

		render(_width, h, srcImg, target, 0);

		return target;
	}

	/**
	 * 调整大小：170*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize170(InputStream in, OutputStream target) {
		Image srcImg = toImage(in);
		if (srcImg.getWidth(null) < WIDTH170) {
			resize(srcImg.getWidth(null), srcImg, target);
			return;
		}
		resize(WIDTH170, srcImg, target);
	}

	/**
	 * 调整大小：170*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize170(Image image, OutputStream target) {
		if (image == null || target == null) {
			return;
		}
		// resize(WIDTH170, image, target,1.0f);
		render2(WIDTH170, WIDTH170, image, target, 1.0f);
	}

	/**
	 * 调整大小：170*auto (会变长)
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize170_define(Image image, OutputStream target) {
		if (image == null || target == null) {
			return;
		}
		resize(WIDTH170, image, target, 1.0f);
		// render2(WIDTH170,WIDTH170,image, target,1.0f);
	}

	/**
	 * 调整大小：198*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize198(Image image, OutputStream target) {
		if (image == null || target == null) {
			return;
		}
		resize(WIDTH198, image, target, 1.0f);
	}

	/**
	 * 调整大小：170*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize30(InputStream in, OutputStream target) {
		Image srcImg = toImage(in);
		if (srcImg.getWidth(null) < WIDTH30) {
			resize(srcImg.getWidth(null), srcImg, target);
			return;
		}
		resize(WIDTH30, srcImg, target);
	}

	/**
	 * 调整大小：30*auto
	 * 
	 * @param image
	 * @param targetImg
	 * @return
	 */
	public static void resize30(Image image, OutputStream target) {
		if (image == null || target == null) {
			return;
		}
		resize(WIDTH30, image, target, 1.0f);
	}

	/**
	 * 调整大小：50*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize50(InputStream in, OutputStream target) {
		Image srcImg = toImage(in);
		if (srcImg.getWidth(null) < WIDTH50) {
			resize(srcImg.getWidth(null), srcImg, target);
			return;
		}
		resize(WIDTH50, srcImg, target);
	}

	/**
	 * 调整大小：50*auto
	 * 
	 * @param image
	 * @param targetImg
	 * @return
	 */
	public static void resize50(Image image, OutputStream target) {
		if (image == null || target == null) {
			return;
		}

		resize(WIDTH50, image, target, 1.0f);
	}

	public static void resize300Me(Image image, OutputStream target) {
		if (image == null || target == null) {
			return;
		}

		render2(WIDTH300, WIDTH300, image, target, 1.0f);
	}

	/**
	 * 调整大小：300*auto
	 * 
	 * @param image
	 * @param targetImg
	 * @return
	 */
	public static void resize300(Image image, OutputStream target) {
		if (image == null || target == null) {
			return;
		}
		if (image.getWidth(null) < WIDTH300) {
			resize(image.getWidth(null), image, target);
			return;
		}

		resize(WIDTH300, image, target);
	}

	/**
	 * 调整大小：300*auto
	 * 
	 * @param image
	 * @param targetImg
	 * @return
	 */
	public static void resize300Max(Image image, OutputStream target) {
		if (image == null || target == null) {
			return;
		}
		/*
		 * if(image.getWidth(null) < WIDTH300 && image.getHeight(null)<
		 * WIDTH300){
		 * 
		 * return; }
		 */

		resizeByMax(WIDTH300, WIDTH300, image, target);
	}

	/**
	 * 调整大小：100*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 */
	public static void resize100(InputStream in, OutputStream target) {
		Image srcImg = toImage(in);
		if (srcImg.getWidth(null) < WIDTH100) {
			resize(srcImg.getWidth(null), srcImg, target);
			return;
		}
		resize(WIDTH100, srcImg, target);
	}

	/**
	 * 调整大小：100*auto
	 * 
	 * @param image
	 * @param targetImg
	 */
	public static void resize100(Image image, OutputStream target) {
		if (image == null || target == null) {
			return;
		}
		if (image.getWidth(null) < WIDTH100) {
			resize(image.getWidth(null), image, target);
			return;
		}
		resize(WIDTH100, image, target);
	}

	/**
	 * 调整大小 : auto*auto 120
	 * 
	 * @param in
	 * @param target
	 */
	public static void resize120(InputStream in, OutputStream target) {
		Image srcImg = toImage(in);
		resize120(srcImg, target);
	}

	public static void resize120(Image srcImg, OutputStream target) {
		int _width = srcImg.getWidth(null);
		int _height = srcImg.getHeight(null);
		if (_width >= _height) {
			// 偏宽
			if (_width <= LENGTH120)
				return;
			else {
				float s = getRatio(_width, LENGTH120);
				int h = (int) (_height * s);
				render2(LENGTH120, h, srcImg, target, 0);
			}
		} else {
			// 偏宽
			if (_height <= LENGTH120)
				return;
			else {
				float s = getRatio(_height, LENGTH120);
				int w = (int) (_width * s);
				render2(w, LENGTH120, srcImg, target, 0);
			}
		}
	}

	/**
	 * 调整大小：360*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize360(InputStream in, OutputStream target) {
		Image srcImg = toImage(in);
		int width = srcImg.getWidth(null);
		if (width < WIDTH360) {
			resize(width, srcImg, target);
			return;
		}
		resize(WIDTH360, srcImg, target);
	}

	/**
	 * 调整大小：440*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize440(InputStream in, OutputStream target) {
		Image srcImg = toImage(in);
		resize440(srcImg, target);
	}

	public static void resize440(Image srcImg, OutputStream target) {
		int width = srcImg.getWidth(null);
		if (width <= WIDTH440) {
			resize(width, srcImg, target);
			return;
			// if(width <= LENGTH120){
			// resize120(srcImg,target);
			// }
			// if(width >= height)
			// return;
		}
		resize(WIDTH440, srcImg, target);
	}

	/**
	 * 调整大小：966*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize966(InputStream in, OutputStream target) {
		Image srcImg = toImage(in);
		int width = srcImg.getWidth(null);
		if (width <= WIDTH966) {
			resize(width, srcImg, target);
			return;
			// if(width <= WIDTH440){
			// resize440(srcImg,target);
			// }
			// if(width >= height)
			// return;
		}
		resize(WIDTH966, srcImg, target);
	}

	public static void resize966(Image image, OutputStream target) {
		int width = image.getWidth(null);
		if (width <= WIDTH966) {
			resize(width, image, target);
			return;
			// if(width <= WIDTH440){
			// resize440(image,target);
			// }
			// if(width >= height)
			// return;
		}
		resize(WIDTH966, image, target);
	}

	/**
	 * 调整大小：_width*auto
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static void resize(int _width, InputStream in, OutputStream target) {
		Image srcImg = toImage(in);
		if (srcImg.getWidth(null) < _width)
			return;
		resize(_width, srcImg, target);
	}

	public static void resize(int _width, Image srcImg, OutputStream out) {
		int width = srcImg.getWidth(null);
		int height = srcImg.getHeight(null);

		float s = getRatio(width, _width);
		int h = (int) (height * s);

		render2(_width, h, srcImg, out, MEDIUM_QUALITY);
	}

	public static void resizeH(int _height, Image srcImg, OutputStream out) {
		int width = srcImg.getWidth(null);
		int height = srcImg.getHeight(null);

		float s = getRatio(height, _height);
		int w = (int) (width * s);

		render2(w, _height, srcImg, out, 0);
	}

	public static void resizeByMax(int targetw, int targeth, InputStream in, OutputStream out) {
		resizeByMax(targetw, targeth, toImage(in), out);
	}

	public static void resizeByMax(int targetw, int targeth, Image srcImg, OutputStream out) {
		int width = srcImg.getWidth(null);
		int height = srcImg.getHeight(null);

		float sx = getRatio(width, targetw);
		float sy = getRatio(height, targeth);
		if (sx > sy) {
			sx = sy;
			targetw = (int) (sx * width);
		} else if (sy > sx) {
			sy = sx;
			targeth = (int) (sy * height);
		} else if (sx != 1) {
			sx = sy;
			targetw = (int) (sx * width);
		} else {
			targetw = width;
			targeth = height;
		}
		render2(targetw, targeth, srcImg, out, 1.0f);

	}

	public static void resize(int _width, Image srcImg, OutputStream out, float quaty) {
		int width = srcImg.getWidth(null);
		int height = srcImg.getHeight(null);

		float s = getRatio(width, _width);
		int h = (int) (height * s);

		render2(_width, h, srcImg, out, quaty);
	}

	/**
	 * 图片压缩<br>
	 * 不改变大小<br>
	 * 
	 * @param src
	 * @param target
	 * @return
	 */
	public static void compress(String src, String target) {
		// 1?动画图片需要压缩不
		// 2?多大容积的图片就不要压缩了
		// 3？
		File srcFile = checkForNull(src);
		Image srcImg = toImage(srcFile);
		int width = srcImg.getWidth(null);
		int height = srcImg.getHeight(null);
		float quality = getScaleSpace(srcFile.length(), width, height);

		render(width, height, srcImg, target, quality);
	}

	public Image loadImage(String src) {
		Image srcImg = null;
		File srcFile = checkForNull(src);
		srcImg = toImage(srcFile);
		return srcImg;

	}

	/**
	 * 图片压缩<br>
	 * 不改变大小<br>
	 * 
	 * @param src
	 * @param target
	 * @return
	 */
	public static void compress(InputStream in, OutputStream out, int len) {
		Image srcImg = toImage(in);
		int width = srcImg.getWidth(null);
		int height = srcImg.getHeight(null);
		float quality = getScaleSpace(len, width, height);

		render2(width, height, srcImg, out, quality);
	}

	public static void compress(BufferedImage bi, OutputStream out, long len) {
		if (bi == null) {
			return;
		}
		int width = bi.getWidth(null);
		int height = bi.getHeight(null);
		float quality = getScaleSpace(len, width, height);

		render2(width, height, bi, out, quality);
	}

	/**
	 * @param pressText
	 *            水印文字
	 * @param srcImg
	 *            源文件
	 * @param targetImg
	 *            结果文件
	 * @param type
	 *            水印位置
	 */
	public static void watermarkText(String pressText, String srcImg, String targetImg, String type) {
		pressText(pressText, srcImg, targetImg, type);
		// pressText(pressText, srcImg, targetImg, fontName, fontStyle, color,
		// fontSize, x, y, type);
	}

	public static String watermarkImg() {
		return null;
	}

	/**
	 * 压缩图片<br>
	 * 默认比例：width:966 height:auto<br>
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static String zip(String srcImg, String targetImg) {
		if (srcImg == null) {
			return null;
		}
		return zip(new File(srcImg), targetImg, WIDTH966);
	}

	/**
	 * 压缩图片
	 * 
	 * @param srcImg
	 * @param width
	 * @param height
	 * @param quality
	 * @param targetImg
	 * @return
	 */
	public static String zip(String srcImg, int width, int height, float quality, String targetImg, int _w) {
		//FileOutputStream out = null;
		if (width == 0 && height == 0 && quality == 0)
			return zip(srcImg, targetImg);

		if (srcImg == null) {
			return null;
		}

		return zip(new File(srcImg), width, height, quality, targetImg, _w);
	}

	/**
	 * 压缩图片<br>
	 * 压缩占用空间<br>
	 * 压缩长宽：width:966 height:auto<br>
	 * 如果width<966,只压缩图片占用空间
	 * 
	 * @param srcImg
	 * @param targetImg
	 * @return
	 */
	public static String zip(File srcImg, String targetImg, int w) {
		if (srcImg == null) {
			return null;
		}
		FileOutputStream out = null;
		int width = -1;
		int height = -1;
		try {

			// 对临时文件进行处理
			Image srcFile = ImageIO.read(srcImg);
			width = srcFile.getWidth(null); // 得到源图宽
			height = srcFile.getHeight(null); // 得到源图长

			float quality = getScaleSpace(srcImg.length(), width, height);

			float s = getRatio(width, w);
			int h = (int) (height * s);

			BufferedImage tag = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
			tag.getGraphics().drawImage(srcFile, 0, 0, w, h, null);
			out = new FileOutputStream(targetImg); // 压缩后的新图
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
			jep.setQuality(quality, true); // 压缩质量
			encoder.encode(tag, jep);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return targetImg;
	}

	/**
	 * 压缩图片
	 * 
	 * @param srcImg
	 * @param width
	 * @param height
	 * @param quality
	 * @param targetImg
	 * @return
	 */
	public static String zip(File srcImg, int width, int height, float quality, String targetImg, int _w) {
		FileOutputStream out = null;
		if (width == 0 && height == 0 && quality == 0)
			return zip(srcImg, targetImg, _w);

		if (srcImg == null) {
			return null;
		}
		try {
			Image srcFile = ImageIO.read(srcImg);
			BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			tag.getGraphics().drawImage(srcFile, 0, 0, width, height, null);
			out = new FileOutputStream(targetImg);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
			jep.setQuality(quality, true);
			encoder.encode(tag, jep);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return targetImg;
	}

	public void cutout() {
	}

	public void press() {
	}

	/**
	 * 复制文件<br>
	 * 文件存放位置、上传的文件、文件名称<br>
	 * 
	 * @param directory
	 * @param src
	 * @param fileName
	 * @return 上传后的文件名
	 */
	public static String copyFile(String directory, File src, String fileName) {
		if (directory == null || "".equals(directory))
			return null;
		try {
			String suffix = getFileSuffix(fileName);
			String targetName = makeFileName(suffix);
			File target = new File(directory, targetName);
			FileUtils.copyFile(src, target);

			return target.getAbsolutePath();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 创建文件<br>
	 * 文件存放位置、文件名称<br>
	 * 
	 * @param directory
	 * @param fileName
	 * @return 上传后的文件名
	 */
	public static String newFile(String directory, String fileName) {
		if (directory == null || "".equals(directory))
			return null;
		try {
			String suffix = getFileSuffix(fileName);
			String targetName = makeFileName(suffix);
			File target = new File(directory, targetName);
			// FileUtils.writeStringToFile(target, "");
			return target.getAbsolutePath();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 把图片印刷到图片上
	 * 
	 * @param pressImg
	 *            水印文件
	 * @param targetImg
	 *            目标文件
	 * @param x
	 * @param y
	 */
	public final static void pressImage(String pressImg, String srcImg, String targetImg, int x, int y) {
		FileOutputStream out = null;

		if (srcImg == null) {
			return;
		}

		try {
			File _file = new File(srcImg);
			Image src = ImageIO.read(_file);
			int width = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

			Graphics g = image.createGraphics();
			g.drawImage(src, 0, 0, width, height, null);

			// 水印文件
			File _filewatermark = new File(pressImg);
			Image watermarkSrc = ImageIO.read(_filewatermark);
			int watermarkW = watermarkSrc.getWidth(null);
			int watermarkH = watermarkSrc.getHeight(null);
			g.drawImage(watermarkSrc, width - watermarkW - x, height - watermarkH - y, watermarkW, watermarkH, null);
			g.dispose();
			out = new FileOutputStream(targetImg);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(image);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 文字添加水印
	 * 
	 * @param pressText
	 * @param srcImg
	 * @param targetImg
	 * @param type
	 */
	public static void pressText(String pressText, String srcImg, String targetImg, String type) {

		pressText(pressText, srcImg, targetImg, _FONTNAME, _FONTSTYLE, _COLOR, 0, 0, 0, type);

	}

	/**
	 * 把文字印刷到图片上
	 * 
	 * @param pressText
	 *            文字
	 * @param targetImg
	 *            目标图片
	 * @param fontName
	 *            字体名
	 * @param fontStyle
	 *            字体样式
	 * @param color
	 *            字体颜色
	 * @param fontSize
	 *            字体大小
	 * @param x
	 *            偏移量
	 * @param y
	 */
	public static void pressText(String pressText, String srcImg, String targetImg, String fontName, int fontStyle,
			int color, int fontSize, int x, int y, String type) {
		FileOutputStream out = null;

		if (srcImg == null) {
			return;
		}

		try {
			File _file = new File(srcImg);
			Image src = ImageIO.read(_file);
			int width = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			Graphics g = image.createGraphics();
			g.drawImage(src, 0, 0, width, height, null);
			g.setColor(Color.WHITE);
			if (fontSize == 0)
				fontSize = getFontSize(width, pressText);

			g.setFont(new Font(fontName, fontStyle, fontSize));
			FontMetrics fm = g.getFontMetrics();

			if (BOTTOM_RIGTH.equals(type)) {
				g.drawString(pressText, width - fm.stringWidth(pressText), height - fm.getDescent());
			} else if (BOTTOM_LEFT.equals(type)) {
				g.drawString(pressText, 0, height - fm.getDescent());
			} else {
				g.drawString(pressText, (width - (pressText.length() * fontSize)) / 2 + x, (height - fontSize) / 2 + y);
			}

			g.dispose();
			out = new FileOutputStream(targetImg);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(image);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 添加水印文件，对流的处理
	 * 
	 * @param pressText
	 * @param srcImg
	 * @param targetImg
	 * @param type
	 */
	public static void pressText2(String pressText, InputStream srcImg, OutputStream targetImg, String type) {
		pressText2(pressText, srcImg, targetImg, _FONTNAME, _FONTSTYLE, _COLOR, 0, 0, 0, type);
	}

	public static void pressText2(String pressText, InputStream srcImg, OutputStream targetImg, String fontName,
			int fontStyle, int color, int fontSize, int x, int y, String type) {
		if (srcImg == null) {
			return;
		}
		try {
			Image src = toImage(srcImg);

			int width = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			Graphics g = image.createGraphics();
			g.drawImage(src, 0, 0, width, height, null);
			g.setColor(Color.WHITE);
			if (fontSize == 0)
				fontSize = getFontSize(width, pressText);

			g.setFont(new Font(fontName, fontStyle, fontSize));
			FontMetrics fm = g.getFontMetrics();
			int paddingBottom = (int) (fm.getDescent() / 2.0F);
			int paddingLeft = fm.stringWidth("A");
			int paddingRight = paddingLeft;

			if (BOTTOM_RIGTH.equals(type)) {
				g.drawString(pressText, width - fm.stringWidth(pressText) - paddingRight,
						height - fm.getDescent() - paddingBottom);
			} else if (BOTTOM_LEFT.equals(type)) {
				g.drawString(pressText, 0 + paddingLeft, height - fm.getDescent() - paddingBottom);
			} else {
				g.drawString(pressText, (width - (pressText.length() * fontSize)) / 2 + x, (height - fontSize) / 2 + y);
			}

			g.dispose();
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(targetImg);
			encoder.encode(image);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {

		}
	}

	public static void rotate(String srcImg, String targetImg, int degree) {
		if (srcImg == null) {
			return;
		}
		File _file = new File(srcImg);
		Image src;
		FileOutputStream out = null;
		try {
			src = ImageIO.read(_file);
			int width = src.getWidth(null);
			int height = src.getHeight(null);

			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

			Graphics2D g = image.createGraphics();
			// g.drawImage(src, 0, 0, width, height, null);
			g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

			g.rotate(Math.toRadians(degree), width / 2, height / 2);
			g.drawImage(src, 0, 0, null);
			g.dispose();

			out = new FileOutputStream(targetImg);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(image);

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@SuppressWarnings("unused")
	private int getAutoWidth(int oldWidth) {
		return 0;
	}

	/**
	 * 获取长度缩小比例
	 * 
	 * @param oldWdith
	 * @param newWidth
	 * @return
	 */
	private static float getRatio(int oldWidth, int newWidth) {
		if (oldWidth == 0 || oldWidth < newWidth)
			return 1F;
		float s = (float) newWidth / oldWidth;
		return s;
	}

	/**
	 * 获取图片占用空间压缩的比例
	 * 
	 * @param fileSize
	 * @return
	 */
	private static float getScaleSpace(long fileSize, int width, int height) {
		// XXX: 处理压缩空间
		if (fileSize <= FIVE_SIZE_M && fileSize > FOUR_SIZE_M) {
			return LOWEST_QUALITY;
		} else if (fileSize <= FOUR_SIZE_M && fileSize > THREE_SIZE_M) {
			return LOW_QUALITY;
		} else if (fileSize <= THREE_SIZE_M && fileSize > TWO_SIZE_M) {
			return DEFALUT_QUALITY;
		} else if (fileSize <= TWO_SIZE_M && fileSize > ONE_SIZE_M) {
			return MEDIUM_QUALITY;
		} else {
			return HIGH_QUALITY;
		}
	}

	/**
	 * 删除多个文件
	 * 
	 * @param paths
	 */
	public static void deleteFiles(List<String> paths) {
		for (String path : paths)
			deleteFile(path);
	}

	/**
	 * 删除单个文件
	 * 
	 * @param path
	 * @return
	 */
	public static boolean deleteFile(String path) {
		boolean flag = false;
		File f = new File(path);
		if (f.exists())
			flag = f.delete();
		else
			return true;
		return flag;
	}

	/**
	 * 重命名<br>
	 * 绝对路径\文件名.后缀<br>
	 * c:\123.jpg<br>
	 * 
	 * @param path
	 * @param oldFileName
	 * @return
	 */
	public static String makeFileName(String path, String oldFileName) {
		String suffix = getFileSuffix(oldFileName);
		return path + File.separator + makeFileName(suffix);
	}

	/**
	 * 重命名<br>
	 * 文件名.后缀<br>
	 * 123.jpg<br>
	 * 
	 * @param prex
	 * @return
	 */
	public static String makeFileName(String prex) {
		return UUIDHelper.uuid() + prex;
	}

	/**
	 * 重命名<br>
	 * 文件名<br>
	 * 123<br>
	 * 
	 * @param prex
	 * @return
	 */
	public static String makeFileName() {
		return UUIDHelper.uuid();
	}

	public static String reFileName(String fileName, String prex) {
		String suffix = getFileSuffix(fileName);
		if (suffix == null || "".equals(suffix))
			return null;
		if (!fileName.contains("."))
			return null;
		return new String(fileName.substring(0, fileName.lastIndexOf('.')) + prex + suffix);
	}

	public static BufferedImage cut(int x, int y, int width, int height, String src) throws IOException {
		BufferedImage bi = null;
		//File srcFile = checkForNull(src);

		FileInputStream is = null;
		ImageInputStream iis = null;

		try {
			// 读取图片文件
			is = new FileInputStream(src);
			/*
			 * 返回包含所有当前已注册 ImageReader 的 Iterator，这些 ImageReader 声称能够解码指定格式。
			 * 参数：formatName - 包含非正式格式名称 . （例如 "jpeg" 或 "tiff"）等 。
			 */
			String fileType = getFileType(src);
			Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(fileType);
			ImageReader reader = it.next();
			// 获取图片流
			iis = ImageIO.createImageInputStream(is);

			/*
			 * <p>iis:读取源.true:只向前搜索 </p>.将它标记为 ‘只向前搜索’。
			 * 此设置意味着包含在输入源中的图像将只按顺序读取，可能允许 reader 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。
			 */
			reader.setInput(iis, true);

			/*
			 * <p>描述如何对流进行解码的类<p>.用于指定如何在输入时从 Java Image I/O
			 * 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件 将从其 ImageReader 实现的
			 * getDefaultReadParam 方法中返回 ImageReadParam 的实例。
			 */
			ImageReadParam param = reader.getDefaultReadParam();

			/*
			 * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域，通过 Rectangle 对象
			 * 的左上顶点的坐标（x，y）、宽度和高度可以定义这个区域。
			 */
			Rectangle rect = new Rectangle(x, y, width, height);

			// 提供一个 BufferedImage，将其用作解码像素数据的目标。
			param.setSourceRegion(rect);

			/*
			 * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象，并将 它作为一个完整的
			 * BufferedImage 返回。
			 */
			bi = reader.read(0, param);
		} finally {
			if (is != null)
				is.close();
			if (iis != null)
				iis.close();

		}
		return bi;

	}

	/**
	 * 获取文件后缀
	 * 
	 * @param fileName
	 * @return
	 */
	public static String getFileSuffix(String fileName) {
		if (fileName == null || "".equals(fileName))
			return null;
		if (!fileName.contains("."))
			return null;
		return new String(fileName.substring(fileName.lastIndexOf('.'), fileName.length()));
	}

	public static String getFileName(String fileName) {
		if (fileName == null || "".equals(fileName))
			return null;
		if (!fileName.contains("."))
			return null;
		return new String(fileName.substring(0, fileName.lastIndexOf('.')));
	}

	/**
	 * 获取文件后缀
	 * 
	 * @param fileName
	 * @return
	 */
	public static String getFileType(String fileName) {
		if (fileName == null || "".equals(fileName))
			return null;
		if (!fileName.contains("."))
			return null;
		return new String(fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length()));
	}

	/**
	 * 根据图片的大小设置水印字体大小
	 * 
	 * @param width
	 * @return
	 */
	public static int getFontSize(int width) {
		int default_width = 1024;
		int default_size = 42;
		float s = (float) width / default_width;
		return (int) (default_size * s);
	}

	public static int getFontSize(int width, String markText) {
		/*
		 * int default_width = 1024; int default_size = 42; float s = (float)
		 * width / default_width; return (int)(default_size * s);
		 */
		int textLen = markText.length();
		int textPx = (int) (width * 0.2);
		int pxOfchar = textPx / textLen;
		int fontSize = 72 * pxOfchar / 96;
		return fontSize;
	}

	@SuppressWarnings("resource")
	public static void main(String[] args) throws Exception {

		// BufferedImage bi = cutImage(0,0,50,50,"D:\\Backup\\我的文档\\My
		// Pictures\\graham11-hp-sprite.png");
		// Image image =bi;
		// File file = new File("D:\\Backup\\我的文档\\My
		// Pictures\\graham11-hp-sprite.png");
		InputStream input = new BufferedInputStream(
				new FileInputStream("D:\\Backup\\我的文档\\My Pictures\\graham11-hp-sprite.png"));
		ByteArrayOutputStream middleOut = new ByteArrayOutputStream();
		resize100(input, middleOut);

		OutputStream outputStream = new BufferedOutputStream(new FileOutputStream("D:\\test.jpg"));
		ByteArrayOutputStream tmp = middleOut;
		InputStream is = new ByteArrayInputStream(tmp.toByteArray());
		byte[] bytes = new byte[1024];
		int readBye;
		while ((readBye = is.read(bytes)) != -1) {
			outputStream.write(bytes, 0, readBye);
			System.out.println(readBye);
		}
		outputStream.flush();
	}

	/**
	 * 将图片进行裁剪
	 * 
	 * @author kongqz
	 * @param imgsrc
	 *            源图片文件路径
	 * @param suffix
	 *            文件的后缀
	 * @param imgdest
	 *            目标图片文件写入路径
	 * @param x
	 *            图片的x坐标
	 * @param y
	 *            图片的y坐标
	 * @param width
	 *            截取框的宽
	 * @param height
	 *            截取框的高
	 * @throws IOException
	 */
	public static BufferedImage cutImage(int x, int y, int width, int height, String url) throws IOException {
		// 进行截取
		// 读取源图片文件
		BufferedImage sourceImage = ImageIO.read(new URL(url));
		
		Image croppedImage;//图片对象
		ImageFilter cropFilter;//裁剪对象
		// 四个参数分别为图像起点坐标和宽高，即CropImageFilter(int x,int y,int width,int height)
		// 指定要裁剪的的文件的宽度和高度，以及起始坐标
		cropFilter = new CropImageFilter(x, y, width, height);
		// 生成图片
		croppedImage = Toolkit.getDefaultToolkit()
				.createImage(new FilteredImageSource(sourceImage.getSource(), cropFilter));

		// 获取创建后的图片的高度
		int h1 = croppedImage.getHeight(null);//图片加载到内存中，可获图片真实高度
		int w1 = croppedImage.getWidth(null);//图片加载到内存中，可获图片真实宽度

		//BufferedImage是Image的一个子类，BufferedImage生成的图片在内存里有一个图像缓冲区，利用这个缓冲区我们可以很方便的操作这个图片，通常用来做图片修改操作如大小变换、图片变灰、设置图片透明或不透明
		BufferedImage bi = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_RGB);

		Graphics g = bi.getGraphics();
		// 在画图的时候可以设置背景色
		g.drawImage(croppedImage, 0, 0, Color.white, null);
		g.dispose();
		/*
		 * //创建要存储图片的文件,如果文件存在就读取 File file = new File(imgdest); //删除文件
		 * file.delete(); //创建文件输出流 FileOutputStream fos=new
		 * FileOutputStream(new File(imgdest)); //将创建的图片写入到输出流 ImageIO.write(bi,
		 * suffix, fos); fos.close();
		 */
		return bi;
	}
	
	
}
